package com.isoftstone.framework.shiro;

import com.isoftstone.common.constant.Constants;
import com.isoftstone.project.system.domain.SysUser;
import com.isoftstone.project.system.service.ISysMenuService;
import com.isoftstone.project.system.service.ISysUserRoleService;
import com.isoftstone.project.system.service.ISysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author ztc
 *  2015-3-6
 */
public class ShiroRealm extends AuthorizingRealm {

	@Autowired
	ISysUserService sysUserService;

	@Autowired
	ISysUserRoleService sysUserRoleService;

	@Autowired
	ISysMenuService sysMenuService;
	@Override
	public boolean supports(AuthenticationToken token) {
		return token != null && token instanceof UsernamePasswordToken;
	}
	/*
	 * 由于定义了两个realm  这里只能抛出AuthenticationException 异常
	 * 登录信息和用户验证信息验证(non-Javadoc)
	 * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		SysUser user;
		try {
			user = sysUserService.getSysUserById(authcToken.getPrincipal().toString());
		} catch (Exception e) {
			throw new UnknownAccountException("账号或密码错误!");
		}
		SimpleAuthenticationInfo info = null;
  		if(null != user){
			info =  new SimpleAuthenticationInfo(user.getUserId(),user.getPassWord(), getName());
			Session session = SecurityUtils.getSubject().getSession();
			session.setAttribute(Constants.SESSION_USER, user);			//把用户信息放session中
			return info;
		}else{
			throw new UnknownAccountException("账号或密码错误!");
		}
	}


	/*
	 * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用,负责在应用程序中决定用户的访问控制的方法(non-Javadoc)
	 * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
		SimplePrincipalCollection principalCollection = (SimplePrincipalCollection) principals;
		//List<Object> listPrincipals = principalCollection.asList();
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		if(!(principalCollection.getPrimaryPrincipal() instanceof UsernamePasswordToken)){
			try {
				Session session = SecurityUtils.getSubject().getSession();
				SysUser user = (SysUser)session.getAttribute(Constants.SESSION_USER);
//
				List<String> roleList = sysUserRoleService.getRolesByUserId(user.getUserId());
				authorizationInfo.addRoles(roleList);

				List<String> menus = sysMenuService.getMenuByUserId(user.getUserId());
				authorizationInfo.addStringPermissions(menus);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return authorizationInfo;
	}
	public void clearCached() {
		PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
		super.clearCache(principals);
	}
}
